﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace WindowsFormsApplication1.wtyczki
{
    class basicMatrix
    {
        public static Bitmap multiply(Bitmap bm, int _m00, int _m01, int _m02, int _m10, int _m11, int _m12, int _m20, int _m21, int _m22)
        {
            myRGB[,] bmTemp= new myRGB[bm.Width, bm.Height];
            for (int x = 0; x < bm.Width; x++)
            {
                for (int y = 0; y < bm.Height; y++)
                {
                    bmTemp[x, y] = new myRGB();
                }
            }
            int r = 0, g = 0, b = 0;
            int m00 = _m00, m01 = _m01, m02 = _m02;
            int m10 = _m10, m11 = _m11, m12 = _m12;
            int m20 = _m20, m21 = _m21, m22 = _m22;

            for (int x = 0; x < bm.Width; x++)
            {
                for (int y = 0; y < bm.Height; y++)
                {

                    if (y == 0 && x == 0) //upper left corner
                    {
                        r = (bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12 + bm.GetPixel(x, y + 1).R * m21 + bm.GetPixel(x + 1, y + 1).R * m22) / 4;
                        g = (bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12 + bm.GetPixel(x, y + 1).G * m21 + bm.GetPixel(x + 1, y + 1).G * m22) / 4;
                        b = (bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12 + bm.GetPixel(x, y + 1).B * m21 + bm.GetPixel(x + 1, y + 1).B * m22) / 4;
                    }
                    if (y == 0 && (x != 0 && x < (bm.Width - 1)))//upper line
                    {
                        r = (bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12 + bm.GetPixel(x - 1, y + 1).R * m20 + bm.GetPixel(x, y + 1).R * m21 + bm.GetPixel(x + 1, y + 1).R * m22) / 6;
                        g = (bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12 + bm.GetPixel(x - 1, y + 1).G * m20 + bm.GetPixel(x, y + 1).G * m21 + bm.GetPixel(x + 1, y + 1).G * m22) / 6;
                        b = (bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12 + bm.GetPixel(x - 1, y + 1).B * m20 + bm.GetPixel(x, y + 1).B * m21 + bm.GetPixel(x + 1, y + 1).B * m22) / 6;
                    }
                    if (y == 0 && x == (bm.Width - 1))//upper right corner
                    {
                        r = (bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x - 1, y + 1).R * m20 + bm.GetPixel(x, y + 1).R * m21) / 4;
                        g = (bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x - 1, y + 1).G * m20 + bm.GetPixel(x, y + 1).G * m21) / 4;
                        b = (bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x - 1, y + 1).B * m20 + bm.GetPixel(x, y + 1).B * m21) / 4;
                    }
                    if ((y != 0 && y < (bm.Height - 1)) && (x != 0 && x < (bm.Width - 1)))//middle
                    {
                        r = (bm.GetPixel(x - 1, y - 1).R * m00 + bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x + 1, y - 1).R * m02 + bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12 + bm.GetPixel(x - 1, y + 1).R * m20 + bm.GetPixel(x, y + 1).R * m21 + bm.GetPixel(x + 1, y + 1).R * m22) / 9;
                        g = (bm.GetPixel(x - 1, y - 1).G * m00 + bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x + 1, y - 1).G * m02 + bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12 + bm.GetPixel(x - 1, y + 1).G * m20 + bm.GetPixel(x, y + 1).G * m21 + bm.GetPixel(x + 1, y + 1).G * m22) / 9;
                        b = (bm.GetPixel(x - 1, y - 1).B * m00 + bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x + 1, y - 1).B * m02 + bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12 + bm.GetPixel(x - 1, y + 1).B * m20 + bm.GetPixel(x, y + 1).B * m21 + bm.GetPixel(x + 1, y + 1).B * m22) / 9;
                    }
                    if ((y != 0 && y < (bm.Height - 1)) && x == (bm.Width - 1))//right line
                    {
                        r = (bm.GetPixel(x - 1, y - 1).R * m00 + bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x - 1, y + 1).R * m20 + bm.GetPixel(x, y + 1).R * m21) / 6;
                        g = (bm.GetPixel(x - 1, y - 1).G * m00 + bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x - 1, y + 1).G * m20 + bm.GetPixel(x, y + 1).G * m21) / 6;
                        b = (bm.GetPixel(x - 1, y - 1).B * m00 + bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x - 1, y + 1).B * m20 + bm.GetPixel(x, y + 1).B * m21) / 6;
                    }
                    if ((y != 0 && y < (bm.Height - 1)) && x == 0)//left line
                    {
                        r = (bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x + 1, y - 1).R * m02 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12 + bm.GetPixel(x, y + 1).R * m21 + bm.GetPixel(x + 1, y + 1).R * m22) / 6;
                        g = (bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x + 1, y - 1).G * m02 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12 + bm.GetPixel(x, y + 1).G * m21 + bm.GetPixel(x + 1, y + 1).G * m22) / 6;
                        b = (bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x + 1, y - 1).B * m02 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12 + bm.GetPixel(x, y + 1).B * m21 + bm.GetPixel(x + 1, y + 1).B * m22) / 6;
                    }
                    if (y == (bm.Height - 1) && x == 0)//down left corner
                    {
                        r = (bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x + 1, y - 1).R * m02 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12) / 4;
                        g = (bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x + 1, y - 1).G * m02 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12) / 4;
                        b = (bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x + 1, y - 1).B * m02 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12) / 4;
                    }
                    if (y == (bm.Height - 1) && (x != 0 && x < (bm.Width - 1)))//down line
                    {
                        r = (bm.GetPixel(x - 1, y - 1).R * m00 + bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x + 1, y - 1).R * m02 + bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11 + bm.GetPixel(x + 1, y).R * m12) / 6;
                        g = (bm.GetPixel(x - 1, y - 1).G * m00 + bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x + 1, y - 1).G * m02 + bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11 + bm.GetPixel(x + 1, y).G * m12) / 6;
                        b = (bm.GetPixel(x - 1, y - 1).B * m00 + bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x + 1, y - 1).B * m02 + bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11 + bm.GetPixel(x + 1, y).B * m12) / 6;
                    }
                    if (y == (bm.Height - 1) && x == (bm.Width - 1))//down right corner
                    {
                        r = (bm.GetPixel(x - 1, y - 1).R * m00 + bm.GetPixel(x, y - 1).R * m01 + bm.GetPixel(x - 1, y).R * m10 + bm.GetPixel(x, y).R * m11) / 4;
                        g = (bm.GetPixel(x - 1, y - 1).G * m00 + bm.GetPixel(x, y - 1).G * m01 + bm.GetPixel(x - 1, y).G * m10 + bm.GetPixel(x, y).G * m11) / 4;
                        b = (bm.GetPixel(x - 1, y - 1).B * m00 + bm.GetPixel(x, y - 1).B * m01 + bm.GetPixel(x - 1, y).B * m10 + bm.GetPixel(x, y).B * m11) / 4;
                    }
                    bmTemp[x, y].R = r;
                    bmTemp[x, y].G = g;
                    bmTemp[x, y].B = b;
                }
            }
            //Normalization
            int min=0, max=0;
            for (int i = 0; i < bm.Width; i++)
            {
                for (int j = 0; j < bm.Height; j++)
                {
                    if (bmTemp[i, j].R < min)
                        min = bmTemp[i, j].R;
                    if (bmTemp[i, j].G < min)
                        min = bmTemp[i, j].G;
                    if (bmTemp[i, j].B < min)
                        min = bmTemp[i, j].B;

                    if (bmTemp[i, j].R > max)
                        max = bmTemp[i, j].R;
                    if (bmTemp[i, j].G > max)
                        max = bmTemp[i, j].G;
                    if (bmTemp[i, j].B > max)
                        max = bmTemp[i, j].B;
                }
            }
            int roznica = 0 - min;
            for (int i = 0; i < bm.Width; i++)
            {
                for (int j = 0; j < bm.Height; j++)
                {
                    bmTemp[i, j].R = bmTemp[i, j].R + roznica;
                    bmTemp[i, j].G = bmTemp[i, j].G + roznica;
                    bmTemp[i, j].B = bmTemp[i, j].B + roznica;
                }
            }
            for (int i = 0; i < bm.Width; i++)
            {
                for (int j = 0; j < bm.Height; j++)
                {
                    double ss = (double)bmTemp[i, j].R / max;
                    double rd = bmTemp[i, j].R;
                    double gd = bmTemp[i, j].G;
                    double bd = bmTemp[i, j].B;
                    bmTemp[i, j].R = (int)(rd/ (max+roznica) * 255);
                    bmTemp[i, j].G = (int)(gd/ (max+roznica) * 255);
                    bmTemp[i, j].B = (int)(bd/ (max+roznica) * 255);
                    int s = bmTemp[i, j].R;
                }
            }
            Bitmap res =  new Bitmap(bm);
            for (int i = 0; i < bm.Width; i++)
            {
                for (int j = 0; j < bm.Height; j++)
                {
                    int rr = bmTemp[i, j].R;
                    res.SetPixel(i, j, Color.FromArgb(bmTemp[i, j].R, bmTemp[i, j].G, bmTemp[i, j].B));
                    int rs = bmTemp[i, j].R;
                }
            }
            return res;
        }
    }
}
